package com.sali.netty.handler;

import com.sali.netty.NettyClient;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: sali
 * @date: 2025/2/22 下午11:16.
 * @version: 1.0
 */
@Slf4j
public class ClientChannelHandler extends SimpleChannelInboundHandler<String> {

    private NettyClient client;

    public ClientChannelHandler(NettyClient client) {
        this.client = client;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("netty client已连接到netty server:{}", ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("netty client以离开了netty server:{}", ctx.channel().remoteAddress());
        ctx.pipeline().remove(this);
        ctx.channel().close();
        reconnectionAsync(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        log.info("接收到netty server心跳消息：[{}]", msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof IOException) {
            log.warn("exceptionCaught: netty client[{}]和netty server断开了连接", ctx.channel().localAddress());
        } else {
            log.error("netty client throw a error:[message:{}]", cause.getMessage(), cause);
        }
        ctx.pipeline().remove(this);
        ctx.channel().close();
        reconnectionAsync(ctx);
    }

    /**
     * 重新连接
     *
     * @param ctx
     */
    private void reconnectionAsync(ChannelHandlerContext ctx) {
        log.info("5s之后重新建立连接");
        ctx.channel().eventLoop().schedule(() -> client.connectAsync(), 5, TimeUnit.SECONDS);
    }

}
